#include <cmath>
#include <iostream>

#include "Interpolation.h"

namespace Lab6
{
    namespace Problem1
    {
        namespace 
        {
            static const double E = 2.71828183;

            double f1(const double x)
            {
            	return 1.0 / pow(E, x);
            }

            double f2(const double x)
            {
            	return -1.0 / pow(E, x);
            }

            double getPrecisionRatio(const double firstEstimation, const double secondEstimation, const double integral)
            {
                double result = (firstEstimation - integral) / (secondEstimation - integral);
                
            	return (result < 0.0) ? -result : result;
            }
        }
    
        void problem1()
        {
            std::cout << "Lab 6 - Problem 1:" << std::endl;
        
        	// Calculate the integral
        	const double integral = f2(1.0) - f2(0.0);
         
        	// Calculate the precision ratio for composite trapezoid rule
        	// with h = 0.05.
        	double firstEstimation = NumericalAnalysis::CompositeTrapezoidRule(0.0, 1.0, 0.05, f1);
        	double secondEstimation = NumericalAnalysis::CompositeTrapezoidRule(0.0, 1.0, 0.025, f1);
        	
        	// Print results
        	double result = getPrecisionRatio(firstEstimation, secondEstimation, integral);
        	std::cout << "Composite trapezoid precision ratio - h=0.5 = " << result << std::endl;
        	
        	// Calculate the precision ratio for composite trapezoid rule
        	// with h = 0.025.
        	firstEstimation = NumericalAnalysis::CompositeTrapezoidRule(0.0, 1.0, 0.025, f1);
        	secondEstimation = NumericalAnalysis::CompositeTrapezoidRule(0.0, 1.0, 0.0125, f1);

        	// Print results
        	result = getPrecisionRatio(firstEstimation, secondEstimation, integral);
        	std::cout << "Composite trapezoid precision ratio - h=0.25 = " << result << std::endl;
        		
        	// Calculate the precision ratio for composite simpson rule with h=0.5
        	firstEstimation = NumericalAnalysis::CompositeSimpsonRule(0.0, 1.0, 0.05, f1);
        	secondEstimation = NumericalAnalysis::CompositeSimpsonRule(0.0, 1.0, 0.025, f1);

        	// Print results
        	result = getPrecisionRatio(firstEstimation, secondEstimation, integral);
        	std::cout << "Composite simpson precision ratio - h=0.5 = " << result << std::endl;
        	
        	// Calculate the precision ratio for composite simpson rule with h=0.5
        	firstEstimation = NumericalAnalysis::CompositeSimpsonRule(0.0, 1.0, 0.025, f1);
        	secondEstimation = NumericalAnalysis::CompositeSimpsonRule(0.0, 1.0, 0.0125, f1);

        	// Print results
        	result = getPrecisionRatio(firstEstimation, secondEstimation, integral);
        	std::cout << "Composite simpson precision ratio - h=0.25 = " << result << std::endl;
        }    
    }
}
